e5de44
@@ -17,7 +17,9 @@
 package org.springframework.http.converter.xml;
 
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
+import java.io.Reader;
 import java.io.Writer;
 import java.nio.charset.Charset;
 
@@ -25,6 +27,7 @@
import org.simpleframework.xml.Root;
 import org.simpleframework.xml.Serializer;
 import org.simpleframework.xml.core.Persister;
 import org.springframework.beans.TypeMismatchException;
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
 import org.springframework.http.MediaType;
@@ -49,21 +52,40 @@
public class SimpleXmlHttpMessageConverter extends AbstractHttpMessageConverter<
 	
 	private Serializer serializer;
 	
-
 	/**
-	 * Protected constructor that sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes}
+	 * Construct a new {@code SimpleXmlHttpMessageConverter} with a default {@link Serializer#Serializer() Serializer}.
+	 * Sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes}
 	 * to {@code text/xml} and {@code application/xml}, and {@code application/*-xml}.
 	 */
 	public SimpleXmlHttpMessageConverter() {
+		this(new Persister());
+	}
+
+	/**
+	 * Construct a new {@code SimpleXmlHttpMessageConverter} with a customized {@link Serializer#Serializer() Serializer}.
+	 * Sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes}
+	 * to {@code text/xml} and {@code application/xml}, and {@code application/*-xml}.
+	 */
+	public SimpleXmlHttpMessageConverter(Serializer serializer) {
 		super(MediaType.APPLICATION_XML, MediaType.TEXT_XML, MediaType.APPLICATION_WILDCARD_XML);
-		
-		this.serializer = new Persister();
+		setSerializer(serializer);
+	}
+	
+	/**
+	 * Sets the {@code Serializer} for this view. If not set, a default
+	 * {@link Serializer#Serializer() Serializer} is used.
+	 * <p>Setting a custom-configured {@code Serializer} is one way to take further control of the XML serialization
+	 * process.
+	 * @throws IllegalArgumentException if serializer is null
+	 */
+	public void setSerializer(Serializer serializer) {
+		Assert.notNull(serializer, "'serializer' must not be null");
+		this.serializer = serializer;
 	}
 	
 	@Override
 	public boolean canRead(Class<?> clazz, MediaType mediaType) {
-//		return true;
-		return clazz.isAnnotationPresent(Root.class) && canRead(mediaType);
+		return canRead(mediaType);
 	}
 
 	@Override
@@ -78,29 +100,45 @@
public class SimpleXmlHttpMessageConverter extends AbstractHttpMessageConverter<
 	}
 
 	@Override
-	protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException {
-		Assert.notNull(this.serializer, "Property 'serializer' is required");
+	protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) 
+			throws IOException, HttpMessageNotReadableException {
+		
+		Reader source = new InputStreamReader(inputMessage.getBody(), getCharset(inputMessage.getHeaders()));
+		
 		try {
-			Object result = this.serializer.read(clazz, inputMessage.getBody());
+			Object result = this.serializer.read(clazz, source);
 			if (!clazz.isInstance(result)) {
 				throw new TypeMismatchException(result, clazz);
 			}
 			return result;
-		}
-		catch (Exception ex) {
+		} catch (Exception ex) {
 			throw new HttpMessageNotReadableException("Could not read [" + clazz + "]", ex);
 		}
 	}
 
 	@Override
-	protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException {
-		Assert.notNull(this.serializer, "Property 'serializer' is required");
-		try {
-			Writer writer = new OutputStreamWriter(outputMessage.getBody(), DEFAULT_CHARSET.name());
-			this.serializer.write(o, writer);
-		}
-		catch (Exception ex) {
+	protected void writeInternal(Object o, HttpOutputMessage outputMessage) 
+			throws IOException, HttpMessageNotWritableException {
+		
+		Writer out = new OutputStreamWriter(outputMessage.getBody(), getCharset(outputMessage.getHeaders()));
+		
+		try {			
+			this.serializer.write(o, out);
+			out.close();
+		} catch (Exception ex) {
 			throw new HttpMessageNotWritableException("Could not write [" + o + "]", ex);
 		}
 	}
+	
+	
+	// helpers
+	
+	private Charset getCharset(HttpHeaders headers) {
+		if (headers != null && headers.getContentType() != null
+				&& headers.getContentType().getCharSet() != null) {
+			return headers.getContentType().getCharSet();
+		}
+		return DEFAULT_CHARSET;
+	}
+	
 }
